package net.area80.images
{
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.ByteArray;
	
	import hislope.display.MetaBitmapData;
	import hislope.filters.color.ColorRange;
	import hislope.filters.pixelbender.Levels;
	
	import net.blog2t.util.BitmapUtils;
	import net.blog2t.util.BlobDetection;

	public class EyeFinder
	{
		// MEMBERS ////////////////////////////////////////////////////////////////////////////
		
		private var rmin:uint;
		private var gmin:uint;
		private var bmin:uint;
		
		private var rmax:uint;
		private var gmax:uint;
		private var bmax:uint;
		
		private var rgbMin:uint;
		private var rgbMax:uint;
		
		public var eyeAreaHeight:Number;
		public var eyeAreaDeflationX:Number;
		public var eyeAreaDeflationY:Number;
		
		public var sourceBmpData:MetaBitmapData;
		private var activeBmpData:BitmapData;
		private var activePixels:ByteArray;
		
		private var eyeArea:Rectangle = new Rectangle();
		private var outline:Shape = new Shape();
		
		private var maxBlobs:int = 2;
		private var minBlobWidth:int = 5;
		private var minBlobHeight:int = 4;
		private var maxBlobWidth:int = 25;
		private var maxBlobHeight:int = 15;
		private var blobRects:Array = [];
		
		private var levels:Levels = new Levels({autoLevels:true});
		private var colorRange:ColorRange = new ColorRange();
		
		// PARAMETERS /////////////////////////////////////////////////////////////////////////
		
		public var fuziness:Number;
		public var blur:Number;
		public var colorSample:uint;
		public var debug:Boolean;
		private var metaBmpData:MetaBitmapData;
		
		public function EyeFinder(metaBmpData:MetaBitmapData)
		{
			this.metaBmpData = metaBmpData;
			sourceBmpData = new MetaBitmapData(metaBmpData.width,metaBmpData.height);
			activeBmpData
		}
		public function process ():Array {
			metaBmpData.copyTo(sourceBmpData);
			if (metaBmpData.activeRect)
			{
				eyeArea = metaBmpData.activeRect.clone();
				eyeArea.inflate(eyeAreaDeflationX, eyeAreaDeflationY);
				eyeArea.height = int(eyeArea.height * eyeAreaHeight);
				BitmapUtils.blur(sourceBmpData, blur);
				
				activePixels = sourceBmpData.getPixels(eyeArea);
				activePixels.position = 0;
				activeBmpData.fillRect(new Rectangle(0, 0, sourceBmpData.width, sourceBmpData.height), 0x000000);
				/*levels.apply(activeBmpData as MetaBitmapData);*/
				activeBmpData.setPixels(eyeArea, activePixels);
				
				/*levels.restrictToRegion(eyeArea);*/
				
				/*colorRange.restrictToRegion(eyeArea);
				colorRange.fuziness = fuziness;
				colorRange.blur = blur;
				colorRange.sample = 0x000000;
				colorRange.apply(activeBmpData as MetaBitmapData);*/
				
				// replace with color range filter
				
				activeBmpData.lock();
				
				activeBmpData.threshold(activeBmpData, eyeArea, eyeArea.topLeft, "<", rmin << 16, 0, 0x00ff0000, true);
				activeBmpData.threshold(activeBmpData, eyeArea, eyeArea.topLeft, "<", gmin << 8, 0, 0x0000ff00, true);
				activeBmpData.threshold(activeBmpData, eyeArea, eyeArea.topLeft, "<", bmin, 0, 0x000000ff, true);
				activeBmpData.threshold(activeBmpData, eyeArea, eyeArea.topLeft, ">", rmax << 16, 0, 0x00ff0000, true);
				activeBmpData.threshold(activeBmpData, eyeArea, eyeArea.topLeft, ">", gmax << 8, 0, 0x0000ff00, true);
				activeBmpData.threshold(activeBmpData, eyeArea, eyeArea.topLeft, ">", bmax, 0, 0x000000ff, true);
				activeBmpData.threshold(activeBmpData, eyeArea, eyeArea.topLeft, "==", 0xff000000, 0xffffffff, 0xff000000, true);
				
				activeBmpData.unlock();
				
				blobRects = [];
				
				BlobDetection.detect(activeBmpData as BitmapData, blobRects, 0xffffff, minBlobWidth, minBlobHeight, maxBlobWidth, maxBlobHeight, maxBlobs);
				outline.graphics.clear();
				
				if (debug) sourceBmpData.copyPixels(activeBmpData, eyeArea, eyeArea.topLeft);
				
				var point:Point = new Point();
				
				for each (var blobRect:Rectangle in blobRects)
				{
					blobRect.inflate(6, 5);
					outline.graphics.beginFill(0x00ff00, 0.6);
					outline.graphics.drawRect(blobRect.x, blobRect.y, blobRect.width, blobRect.height);
					outline.graphics.endFill();
					
					sourceBmpData.copyPixels(metaBmpData, blobRect, point);
					
					point.x += blobRect.width + 1;
				}
				
				sourceBmpData.draw(outline);
				
				metaBmpData.eyes = blobRects;
				
				return blobRects;
			} else {
				return null;
			}
		}
	}
}